package MicroSpring.common;

import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Properties;
import java.util.concurrent.locks.ReentrantLock;

/*
    resource资源读取工具
 */
public class ResourceValueReader {
    private final static ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
    private final static String YAMLNAME="application.yaml";
    private final static String YMLNAME="application.yml";
    private final static String PROPERNAME="application.properties";
    private static Properties properties;
    private static LinkedHashMap yamlMap;
    private static LinkedHashMap ymlMap;
    private final static ReentrantLock lockForProperties=new ReentrantLock();
    private final static ReentrantLock lockForYaml=new ReentrantLock();
    private final static boolean isProperties;
    private final static boolean isYml;
    private final static boolean isYaml;

    static {
        isProperties= classLoader.getResourceAsStream(PROPERNAME)!=null;
        isYml= classLoader.getResourceAsStream(YMLNAME)!=null;
        isYaml= classLoader.getResourceAsStream(YAMLNAME)!=null;
    }




    public static String getValueByPropertiesKey(String key){
        if (!isProperties || !StringUtils.hasText(key))
            return null;
        if (properties==null){
            lockForProperties.lock();
            InputStream resourceAsStream=null;
            try {
                if (properties==null){
                    resourceAsStream = classLoader.getResourceAsStream(PROPERNAME);
                    properties=new Properties();
                    properties.load(resourceAsStream);
                    if (properties==null)
                        return null;
                    return properties.getProperty(key);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    resourceAsStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                lockForProperties.unlock();
            }
        }
        return properties.getProperty(key);
    }

    public static String getValueByYmlKey(String key){
        if (!isYml || !StringUtils.hasText(key))
            return null;
        if (ymlMap==null){
            lockForYaml.lock();
            try {
                if (ymlMap==null){
                    Yaml yaml=new Yaml();
                    ymlMap = yaml.load(classLoader.getResourceAsStream(YMLNAME));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lockForYaml.unlock();
            }
        }
        String[] keys = key.split("\\.");
        int length = keys.length;
        LinkedHashMap copyMap= (LinkedHashMap) ymlMap.clone();
        String resultValue=null;
        for (int i = 0; i < length; i++) {
            Object value = copyMap.get(keys[i]);
            if (value==null){
                return null;
            }
            else if (i==length-1){
                resultValue=value.toString();
            }
            else {
                copyMap= (LinkedHashMap) value;
            }
        }
        return resultValue;

    }
    public static String getValueByYamlKey(String key){
        if (!isYaml || !StringUtils.hasText(key))
            return null;
        if (yamlMap==null){
            lockForYaml.lock();
            try {
                if (yamlMap==null){
                    Yaml yaml=new Yaml();
                    yamlMap = yaml.load(classLoader.getResourceAsStream(YAMLNAME));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lockForYaml.unlock();
            }
        }
        String[] keys = key.split("\\.");
        int length = keys.length;
        LinkedHashMap copyMap= (LinkedHashMap) yamlMap.clone();
        String resultValue=null;
        for (int i = 0; i < length; i++) {
            Object value = copyMap.get(keys[i]);
            if (value==null){
                return null;
            }
            else if (i==length-1){
                resultValue=value.toString();
            }
            else {
                copyMap= (LinkedHashMap) value;
            }
        }
        return resultValue;
    }
}
